package com.sz.common.base.dao;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.sql.Connection;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * Function: DaoSupport <br>
 * Author: hpeng.wang <br>
 * Date: 2016-11-01 14:11
 */
@Repository("daoSupport")
public class DaoSupport implements Dao {
    @Autowired
    private SqlSessionTemplate sqlSessionTemplate;

    @Override
    public int save(String str, Object obj) {
        return sqlSessionTemplate.insert(str, obj);
    }

    @Override
    public int update(String str, Object obj) {
        return sqlSessionTemplate.update(str, obj);
    }

    /**
     * 批量插入信息.
     *
     * @param str  namespace
     * @param objs 要处理对象的集合
     */
    @Override
    public int batchInsert(String str, List<? extends Object> objs) {
        int batch = 0;
        if (objs == null || objs.size() == 0) {
            return batch;
        }
        SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
        // 批量执行器
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        try {
            for (int i = 0, size = objs.size(); i < size; i++) {
                batch = batch + sqlSession.insert(str, objs.get(i));
                if(i % 500 == 0 || i == size - 1) {
                    sqlSession.flushStatements();
                    sqlSession.commit();
                    sqlSession.clearCache();
                }
            }
            return batch;
        } catch (Exception e) {
            //没有提交的数据可以回滚
            sqlSession.rollback();
            return batch;
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 批量更新信息.
     *
     * @param str  namespace
     * @param objs 要处理对象的集合
     */
    @Override
    public int batchUpdate(String str, List<? extends Object> objs) {
        int batch = 0;
        if (objs == null || objs.size() == 0) {
            return batch;
        }
        SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
        // 批量执行器
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        try {
            for (int i = 0, size = objs.size(); i < size; i++) {
                batch = batch + sqlSession.update(str, objs.get(i));
                if(i % 50 == 0 || i == size - 1) {
                    sqlSession.flushStatements();
                    sqlSession.commit();
                    sqlSession.clearCache();
                }
            }
            return batch;
        } finally {
            sqlSession.close();
        }
    }

    /**
     * 批量删除.
     *
     * @param str  命名空间
     * @param objs 要删除对象的list
     */
    @Override
    public int batchDelete(String str, List<? extends Object> objs) {
        int batch = 0;
        if (objs == null || objs.size() == 0) {
            return batch;
        }
        SqlSessionFactory sqlSessionFactory = sqlSessionTemplate.getSqlSessionFactory();
        // 批量执行器
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        try {
            for (int i = 0, size = objs.size(); i < size; i++) {
                batch = batch + sqlSession.delete(str, objs.get(i));
                if(i % 50 == 0 || i == size - 1) {
                    sqlSession.flushStatements();
                    sqlSession.commit();
                    sqlSession.clearCache();
                }
            }

            return batch;
        } finally {
            sqlSession.close();
        }
    }

    @Override
    public int delete(String str, Object obj) {
        return sqlSessionTemplate.delete(str, obj);
    }

    @Override
    public Object findForObject(String str, Object obj) {

        return sqlSessionTemplate.selectOne(str, obj);
    }

    /**
     * 查找对象.
     *
     * @param <T>
     * @param str 需要请求的名称
     * @param obj 参数名称
     * @param clz 泛型化返回List
     * @return 查找的list对象
     */
    @Override
    public <T> List<T> findForList(String str, Object obj, Class<T> clz) {
        return sqlSessionTemplate.selectList(str, obj);
    }

    @Override
    public Object findForMap(String str, Object obj, String key) {
        return sqlSessionTemplate.selectMap(str, obj, key);
    }

    @Override
    public Timestamp getDbDate() {
        //bugfix:如果在一个session中，此方法多次调用将只获取到一个时间
        Map<String, Object> map = new HashMap<>();
        map.put("random", UUID.randomUUID().toString());
        Timestamp date = sqlSessionTemplate.selectOne("getDbDate", map);
        return date;
    }

    /**
     * 获取Mybatis配置对象
     *
     * @return
     */
    @Override
    public Configuration getConfiguration() {
        return this.sqlSessionTemplate.getConfiguration();
    }

    /**
     * @return
     */
    @Override
    public Connection getConnection() {
        return this.sqlSessionTemplate.getConnection();
    }

    /**
     * 查找对象
     * @param str 需要请求的名称
     * @param clz 泛型化返回List
     * @param <T>
     * @return
     */
    @Override
    public <T> List<T> findForList(String str, Class<T> clz) {
        return sqlSessionTemplate.selectList(str);
    }
}
